home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dtypes.h>
- #include <string.h>
- #include <bios.h>
- #include <conio.h>
-
- #include "code.h"
- #include "host.h"
- #include "newload.h"
- #include "callasm.h"
- #include "newterp.h"
- #include "tconfig.h"
- #include "tiles.h"
-
- #define BASERANGE 40
-
- extern PLAYER players[10];
- extern p_TANK point[10];
- extern BOOL update_scr;
- extern int num_players;
- extern int setbullet;
-
- BOOL usedhit;
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void init_interpreter(p_TANK t)
- * PURPOSE : Initilize parts of T structure used by interpreter
- * :
- * CREATION: 01/09/1989 07:16:16
- */
- void init_interpreter(p_TANK t)
- {
-
- memset(t->var,0,sizeof(t->var));
- t->cline=t->prog;
- t->depth=0;
- t->bwait=0;
- t->boom=FALSE;
- t->jiggle=FALSE;
- t->hit=FALSE;
- t->nhits=0;
- t->cweapon=0;
- t->nomove=FALSE;
- t->channel=0;
- t->automove = FALSE;
- t->autolock = FALSE;
- t->jammer = FALSE;
- t->blockage = 0;
-
- clear_channel(&t->station);
-
- } /* void init_interpreter(p_TANK t) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void interprete(p_TANK t, p_PLAYER p)
- * PURPOSE : Main interpreter function
- * :
- * CREATION: 01/09/1989 07:19:42
- */
- void interprete(p_TANK t, p_PLAYER p)
- {
- p_LINE cl;
- BOOL next;
- int rx1, rx2, rx3;
-
- if (!p->active) return;
-
- cl=t->cline;
-
- if (cl==(0L)) {
- p->active=FALSE;
- t->died=biostime(0,0);
- }
-
- /*
- gotoxy(1,1); explain_line(cl);
- */
-
- next=TRUE; usedhit=FALSE;
-
- restore_under_tank(t);
-
- t->var[CWHEREX] =t->px;
- t->var[CWHEREY] =t->py;
- t->var[CCGDIR] =t->cgpoint;
- t->var[CCTDIR] =t->cpoint;
- t->var[CHIT] =t->hit;
- t->var[CNOMOVE] =t->nomove;
- t->var[CBLOCKAGE]=t->blockage;
- t->var[CMESSAGE] =any_messages(&t->station);
-
- if (t->automove) {
- move_tank(t);
- update_scr=TRUE;
- }
-
- switch(cl->command) {
-
- case BAD : gotoxy(15,23);
- printf("BAD command line encountered");
- break;
-
- case _JLT : if (get_arg(t,&cl->arg1) < get_arg(t,&cl->arg2)) {
- next=FALSE;
- t->cline=get_line_arg(&cl->arg3);
- }
- break;
-
- case _JGT : if (get_arg(t,&cl->arg1) > get_arg(t,&cl->arg2)) {
- next=FALSE;
- t->cline=get_line_arg(&cl->arg3);
- }
- break;
-
- case _GOTO : t->cline=get_line_arg(&cl->arg1);
- next=FALSE;
- break;
-
- case _JEQ : if (get_arg(t,&cl->arg1) == get_arg(t,&cl->arg2)) {
- next=FALSE;
- t->cline=get_line_arg(&cl->arg3);
- }
- break;
-
- case _JNEQ : if (get_arg(t,&cl->arg1) != get_arg(t,&cl->arg2)) {
- next=FALSE;
- t->cline=get_line_arg(&cl->arg3);
- }
- break;
-
- case _CALL : do_call(t,&cl->arg1);
- next=FALSE;
- break;
-
- case _MOVE : if (!t->automove) {
- move_tank(t);
- update_scr=TRUE;
- }
- break;
-
- case _LEFT : turn_tank_left(t);
- break;
-
- case _GLEFT : turn_gun_left(t);
- break;
-
- case _RIGHT : turn_tank_right(t);
- break;
-
- case _GRIGHT : turn_gun_right(t);
- break;
-
- case _FIRE : shoot(t);
- break;
-
- case _RETURN : do_return(t);
- break;
-
- case _SET : store(t,&cl->arg1,get_arg(t,&cl->arg2));
- break;
-
- case _ADD : store(t,&cl->arg1,
- get_arg(t,&cl->arg1)+get_arg(t,&cl->arg2));
- break;
-
- case _RAND : store(t,&cl->arg1,1+(rand() % get_arg(t,&cl->arg2)));
- break;
-
- case _SELECT : t->cweapon=get_arg(t,&cl->arg1)-1;
- break;
-
- case _CHANNEL: t->channel =get_arg(t,&cl->arg1);
- t->var[CCHANNEL] = t->channel;
- break;
-
- case _AUTO : t->automove=get_arg(t,&cl->arg1);
- break;
-
- case _LOCK : t->autolock=get_arg(t,&cl->arg1);
- break;
-
- case _JAMMER : t->jammer=get_arg(t,&cl->arg1);
- break;
-
- case _TX : transmit(t, get_arg(t,&cl->arg1),
- get_arg(t,&cl->arg2),
- get_arg(t,&cl->arg3)
- );
- break;
-
- case _RX : read_message(&t->station, &rx1, &rx2, &rx3);
- store(t,&cl->arg1,rx1);
- store(t,&cl->arg2,rx2);
- store(t,&cl->arg3,rx3);
- break;
-
- case _FACE : rx1=best_turn(t->cpoint,get_arg(t,&cl->arg1));
- if (rx1==1)
- turn_tank_left(t);
- else if (rx1==2)
- turn_tank_right(t);
- break;
-
- case _AIM : rx1=best_turn(t->cgpoint,get_arg(t,&cl->arg1));
- if (rx1==1)
- turn_gun_left(t);
- else if (rx1==2)
- turn_gun_right(t);
- break;
-
- case _CONV : store(t,&cl->arg3,do_conv(t,get_arg(t,&cl->arg1),get_arg(t,&cl->arg2)));
- break;
-
- case _RADAR : if (p->extrasType[RADAR]>0)
- store(t, &cl->arg1, check_radar(t) );
- break;
-
- case _SCOPE : if (p->extrasType[WBSCAN]>0)
- store(t, &cl->arg1, check_scope(t));
- break;
-
- case _SCAN : if (p->extrasType[SCANNER]>0)
- store(t, &cl->arg1,check_scan(t,get_arg(t,&cl->arg2)));
- break;
-
- }
-
- if (usedhit)
- t->hit=FALSE;
-
- if (next)
- t->cline=t->cline->nextline;
-
- display_tank(t);
-
- } /* void interprete(p_TANK t, p_PLAYER p) */
-
- /*-------------------------------------
- * Function : int best_turn(int curr, int dest)
- * Purpose : Calculate which is the best direction to turn to face dest
- * Date : 02/15/1989 22:05:17
- */
- int best_turn(int curr, int dest)
- {
- int turn, num1, num2;
-
- if (curr==dest)
- turn=0;
- else {
- if (curr > dest) {
- num1 = curr-dest;
- num2 = 8+dest-curr;
- } else {
- num1 = 8+curr-dest;
- num2 = dest-curr;
- }
-
- if (num1 < num2)
- turn = 1; /* Move Left, counter-clockwise */
- else if (num1 > num2)
- turn = 2; /* Move right */
- else turn = random(2)+1; /* same dist, any way! */
- }
- return turn;
- } /* int best_turn(int curr, int dest) */
-
- /*-------------------------------------
- * Function : void turn_tank_left(p_TANK t)
- * Purpose : Turn tank counter-clockwise and update registers
- * Date : 02/15/1989 21:55:11
- */
- void turn_tank_left(p_TANK t)
- {
- spin(&t->cpoint,-1);
- if (t->autolock)
- turn_gun_left(t);
-
- } /* void turn_tank_left(p_TANK t) */
-
- /*-------------------------------------
- * Function : void turn_tank_right(p_TANK t)
- * Purpose : Turn tank in clockwise direction
- * Date : 02/15/1989 21:55:57
- */
- void turn_tank_right(p_TANK t)
- {
- spin(&t->cpoint,1);
- if (t->autolock)
- turn_gun_right(t);
-
- } /* void turn_tank_right(p_TANK t) */
-
- /*-------------------------------------
- * Function : void turn_gun_left(p_TANK t)
- * Purpose : Turn tank's gun in counter-clockwise direction
- * Date : 02/15/1989 21:56:21
- */
- void turn_gun_left(p_TANK t)
- {
- spin(&t->cgpoint,-1);
- update_scr=TRUE;
- } /* void turn_gun_left(p_TANK t) */
-
- /*-------------------------------------
- * Function : void turn_gun_right(p_TANK t)
- * Purpose : Turn tanks gun in clockwise direction
- * Date : 02/15/1989 21:56:50
- */
- void turn_gun_right(p_TANK t)
- {
- spin(&t->cgpoint,1);
- update_scr=TRUE;
- } /* void turn_gun_right(p_TANK t) */
-
- /*-------------------------------------
- * Function : void transmit(p_TANK t, int tx1, int tx2, int tx3)
- * Purpose : Transmit tx1,2,&3 to any active listening tanks
- * Date : 02/13/1989 23:19:34
- */
- void transmit(p_TANK t, int tx1, int tx2, int tx3)
- {
- int a;
-
- for (a=0; a<num_players; a++)
- if (players[a].active && t!=point[a] && point[a]->channel==t->channel)
- add_message_to_channel(&point[a]->station, tx1, tx2, tx3);
-
- } /* void transmit(p_TANK t, int tx1, int tx2, int tx3) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void store(p_TANK t, p_ARG a, int n)
- * PURPOSE : Store value N into argument A of tank T
- * :
- * CREATION: 01/09/1989 07:28:27
- */
- void store(p_TANK t, p_ARG a, int n)
- {
- if (a->atype!=SYMBOL) {
- gotoxy(15,23);
- printf("Attempt to assign to constant");
- } else
- t->var[a->value]=n;
- } /* void store(p_TANK t, p_ARG a, int n) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> int get_arg(p_TANK t, p_ARG a)
- * PURPOSE : Get the contents of value pointed to by argument A
- * :
- * CREATION: 01/09/1989 07:31:18
- */
- int get_arg(p_TANK t, p_ARG a)
- {
- int ret;
-
- ret=0;
- if (a->atype==SYMBOL) {
- ret=t->var[a->value];
- if (a->value==CHIT)
- usedhit=TRUE;
- } else if (a->atype==CONSTANT)
- ret=a->value;
- else {
- gotoxy(15,23);
- printf("Attempt to return line_ref in integer");
- }
-
- return ret;
-
- } /* int get_arg(p_TANK t, p_ARG a) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void spin(int *v, int dir)
- * PURPOSE : Spin a tank or gun clockwise or counter-clockwise
- * :
- * CREATION: 01/09/1989 07:44:59
- */
- void spin(int *v, int dir)
- {
- (*v)+=dir;
- if (*v==0) *v=8;
- if (*v==9) *v=1;
- } /* void spin(int *v, int dir) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> p_LINE get_line_arg(p_ARG a)
- * PURPOSE : Return pointer to next line in arg A
- * :
- * CREATION: 01/09/1989 07:51:05
- */
- p_LINE get_line_arg(p_ARG a)
- {
- p_LINE ret;
-
- ret=0L;
- if (a->atype!=LINEREF) {
- gotoxy(15,23);
- printf("Returning lineref of a non-lineref argument");
- } else ret=a->linedest;
- return (ret);
-
- } /* p_LINE get_line_arg(p_ARG a) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void do_call(p_TANK pb, p_ARG pa)
- * PURPOSE : Call subroutine at PA
- * :
- * CREATION: 11/29/1988 14:21:52
- */
- void do_call(p_TANK pb, p_ARG pa)
- {
- if (pb->depth>19) {
- gotoxy(15,23);
- printf("Too many CALL's");
- return;
- }
-
- pb->gosub[pb->depth++]=pb->cline;
- pb->cline=get_line_arg(pa);
-
- } /* void do_call(p_TANK pb, p_ARG pa) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void do_return(p_TANK pb)
- * PURPOSE : Do a return
- * :
- * CREATION: 11/29/1988 14:23:35
- */
- void do_return(p_TANK pb)
- {
- if (pb->depth<1) {
- gotoxy(15,23);
- printf("RETURN without CALL");
- return;
- }
- pb->cline=pb->gosub[--pb->depth];
- } /* void do_return(p_TANK pb) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> void shoot(p_TANK p)
- * PURPOSE : Fire a bullet in current direction
- * :
- * CREATION: 12/05/1988 19:16:09
- */
- void shoot(p_TANK p)
- {
- switch (p->cweapon) {
-
- case ROCKET : setbullet = ROCKET1 + p->cpoint-1;
- break;
-
- case MACH16 : setbullet = BMACH16;
- break;
-
- case LASER : setbullet = LASER15 + ((p->cpoint-1)%4);
- break;
-
- case CANNON : setbullet = CANNONBL;
- break;
-
- default : setbullet = BMACH8;
- break;
- }
-
- switch (p->cgpoint) {
- case 1 : init_bullet(p->px,p->py,0,-1,BASERANGE);
- break;
- case 2 : init_bullet(p->px+1,p->py,1,-1,BASERANGE);
- break;
- case 3 : init_bullet(p->px+1,p->py,1,0,BASERANGE);
- break;
- case 4 : init_bullet(p->px+1,p->py+1,1,1,BASERANGE);
- break;
- case 5 : init_bullet(p->px,p->py+1,0,1,BASERANGE);
- break;
- case 6 : init_bullet(p->px,p->py+1,-1,1,BASERANGE);
- break;
- case 7 : init_bullet(p->px,p->py,-1,0,BASERANGE);
- break;
- case 8 : init_bullet(p->px,p->py,-1,-1,BASERANGE);
- break;
- }
- } /* void v_shoot(p_TANK p) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> int check_radar(p_TANK p)
- * PURPOSE : Look around for close tanks
- * : and return distance
- * CREATION: 12/06/1988 11:49:48
- */
- int check_radar(p_TANK p)
- {
- unsigned int f,d,a;
- int x,y;
-
- p->var[CTEAM]=ALLOUT;
- for (f=40, a=0; a<num_players; a++)
- if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
- x=abs(point[a]->px - p->px);
- y=abs(point[a]->py - p->py);
- d=(x<y) ? y : x;
- if (d<f) {
- p->var[CTEAM]=point[a]->team;
- f=d;
- }
- }
- return ((f==40) ? 0 : f);
- } /* int check_radar(p_TANK p) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> int check_scope(p_TANK p)
- * PURPOSE : Return the direction to the closest tank
- * :
- * CREATION: 01/13/1989 12:55:52
- */
- int check_scope(p_TANK p)
- {
- int f,d,a,t;
- int x,y;
-
- for (t=-1, f=999, a=0; a<num_players; a++)
- if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
- x=abs(point[a]->px - p->px);
- y=abs(point[a]->py - p->py);
- d=(x<y) ? y : x;
- if (d<f) {
- p->var[CTEAM]=point[a]->team;
- f=d; t=a;
- }
- }
-
- if (f==999) {
- p->var[CTEAM]=ALLOUT;
- f=0;
- } else {
- x=point[t]->px - p->px;
- y=point[t]->py - p->py;
-
- if (x==0) {
- if (y<0) f=1; else f=5;
- } else if (y==0) {
- if (x<0) f=7; else f=3;
- } else if (x<0) {
- if (y<0) f=8; else f=6;
- } else {
- if (y<0) f=2; else f=4;
- }
- }
- return f;
-
- } /* int check_scope(p_TANK p) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> int do_conv(p_TANK p, int x, int y)
- * PURPOSE : Return the direction to the closest tank
- * :
- * CREATION: 01/13/1989 12:55:52
- */
- int do_conv(p_TANK p, int x, int y)
- {
- int f,xx,yy;
-
- f =0;
-
- xx=x - p->px;
- yy=y - p->py;
-
- if (xx==0) {
- if (yy<0) f=1; else f=5;
- } else if (yy==0) {
- if (xx<0) f=7; else f=3;
- } else if (xx<0) {
- if (yy<0) f=8; else f=6;
- } else {
- if (yy<0) f=2; else f=4;
- }
- return f;
- }
- /* int do_conv(p_TANK p, int x, int y) */
-
- /*<f>----------------------------------------
- * FUNCTION: <s> int check_scan(p_TANK p, int n)
- * PURPOSE : Perform a scan for robot p in direction n
- * :
- * CREATION: 12/06/1988 14:02:03
- */
- int check_scan(p_TANK p, int n)
- {
- int dx,dy,a,adx, ady;
- BOOL fuzzy;
-
- for (a=0; a<num_players; a++)
- if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
-
- dx=p->px-point[a]->px;
- dy=p->py-point[a]->py;
- adx=abs(dx);
- ady=abs(dy);
- if (abs(adx-ady)<2) fuzzy=TRUE; else fuzzy=FALSE;
-
- p->var[CTEAM]=point[a]->team;
-
- switch (n) {
- case 1 : if ((adx<2) && (dy> 0)) return TRUE;
- break;
- case 2 : if ((dx< 0) && (dy> 0) && fuzzy) return TRUE;
- break;
- case 3 : if ((dx< 0) && (ady<2)) return TRUE;
- break;
- case 4 : if ((dx< 0) && (dy< 0) && fuzzy) return TRUE;
- break;
- case 5 : if ((adx<2) && (dy< 0)) return TRUE;
- break;
- case 6 : if ((dx> 0) && (dy< 0) && fuzzy) return TRUE;
- break;
- case 7 : if ((dx> 0) && (ady<2)) return TRUE;
- break;
- case 8 : if ((dx> 0) && (dy> 0) && fuzzy) return TRUE;
- break;
- }
- }
-
- p->var[CTEAM]=ALLOUT;
- return FALSE;
-
- } /* int check_scan(p_TANK p, int n) */
-